<template>
  <div class="content-box">
    <div class="top-box">
      <!-- 文件路径 -->
      <el-page-header :title="''" @back="goBack">
        <template #content>
          <el-breadcrumb separator="/">
            <el-breadcrumb-item @click="handlePrefixClick()">
              <span class="bucket-path">{{ fileQueryData.bucketName || '全部' }}</span>
            </el-breadcrumb-item>
            <el-breadcrumb-item v-for="(item, index) in prefix" :key="index" @click="handlePrefixClick(item)">
              <span class="file-path">{{ item }}</span>
            </el-breadcrumb-item>
          </el-breadcrumb>
        </template>
      </el-page-header>
      <el-button class="right-btn" type="danger" :disabled="!fileSelectionList.length" @click="handleBatchFileDelete()">批量删除</el-button>
    </div>
    <!-- 文件列表 -->
    <el-table :data="curFileList" v-loading="curFileListLoading" class="file-table" max-height="calc(100vh - 300px)" stripe @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="40" />
      <el-table-column label="名称">
        <template #default="{ row }">
          <div class="file-item">
            <el-popover v-if="row.fileExt == 1">
              <template #reference>
                <img :src="row.url" style="cursor: pointer" />
              </template>
              <template #default>
                <div class="thumb-box" style="max-width: 150px; max-height: 300px">
                  <img :src="row.url" alt="" style="width: 100%; height: 100%" />
                </div>
              </template>
            </el-popover>
            <img v-else :src="getAvatarUrl(row.fileExt)" alt="" />
            <span class="file-name" @click="handleFileClick(row)">{{ row.showName }}</span>
          </div>
        </template>
      </el-table-column>
      <el-table-column label="操作" width="280">
        <template #default="{ row }">
          <el-button size="small" v-if="!row.isFolder" @click="handleDownload(row)">下载</el-button>
          <el-button size="small" type="danger" @click="handleBatchFileDelete(row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>
<script setup>
import { ref, onUnmounted } from 'vue'
import { sysFileSelectList, sysFileDeleteList } from '@/api/file'
import { ElMessageBox, ElMessage } from 'element-plus'
import { download } from '@/utils/tools'

const props = defineProps({
  curBucket: {
    type: Object,
    default: () => {
      return {}
    }
  },
  prefix: {
    type: Array,
    default: () => {
      return []
    }
  },
  pageRefresh: {
    type: Boolean,
    default: false
  },
  showBucketList: {
    type: Boolean,
    default: false
  },
  isAdmin: {
    type: Boolean,
    default: false
  }
})

const fileQueryData = ref({
  bucketName: props.curBucket?.bucketName ? props.curBucket.bucketName : null,
  prefix: null
})
const curFileList = ref(null)
const curFileListLoading = ref(false)
// 获取文件列表
const handleGetBucketFile = async () => {
  curFileListLoading.value = true
  let res = await sysFileSelectList(fileQueryData.value)
  // 将当前路径缓存，用于刷新等
  window.sessionStorage.setItem('fileQueryData.value', JSON.stringify(fileQueryData.value))
  // 因后端返的数据类型不同 需处理
  curFileList.value = res.data.map(item => {
    // 文件夹
    let isFolder = getIsFolder(item)
    if (isFolder) {
      let pathArr = item.split('/')
      let splitName = pathArr[pathArr.length - 2]
      return {
        isFolder: true,
        allName: item, //文件完整路径
        showName: splitName, //用于显示的名称
        splitName: splitName, //由文件完整路径处理后的名称
        ...item
      }
    } else {
      // 文件(无name的是直接丢到文件服务器的文件，有name的是数据库记录的文件)
      if (item.name) {
        let pathArr = item.name.split('/')
        let splitName = pathArr[pathArr.length - 1]
        return {
          isFolder: false,
          allName: item.name, //文件完整路径
          showName: item.oriName, //用于显示的名称
          splitName: splitName, //由文件完整路径处理后的名称
          fileExt: getFileType(splitName),
          ...item
        }
      } else {
        let pathArr = item.split('/')
        let splitName = pathArr[pathArr.length - 1]
        return {
          isFolder: false,
          allName: item,
          showName: splitName,
          splitName: splitName,
          fileExt: getFileType(splitName),
          ...item
        }
      }
    }
  })
  curFileListLoading.value = false
}
if (!props.pageRefresh) {
  handleGetBucketFile()
}

// 文件路径(面包屑)
const prefix = ref(props.prefix)
// 点击文件（文件夹和文件）
const handleFileClick = val => {
  // 判断是文件夹还是文件
  if (val.isFolder) {
    //文件夹
    console.log('prefix.value', prefix.value)
    // if(!prefix.value.find(item => item == val.showName))
    prefix.value.push(val.showName)
    fileQueryData.value.prefix = val.allName
    handleGetBucketFile()
  } else {
    //文件
    handleDownload(val) //下载
  }
}

// 判断是文件夹还是文件（直接丢到文件服务器的文件，是没有数据库记录的，所以其完整信息不会作为一个对象返回，而仅仅是一个地址。可以根据结尾是否包含/来判断）
const getIsFolder = val => {
  return Object.prototype.toString.call(val).slice(8, -1) === 'String' && val.endsWith('/')
}

// 多选
const fileSelectionList = ref([])
const handleSelectionChange = val => {
  fileSelectionList.value = val
}
// 批量删除文件
const handleBatchFileDelete = async val => {
  let des = val.isFolder
    ? `<div><p style="font-size: 16px;margin-bottom: 15px;">是否删除所选文件夹？</p><span style="font-size: 14px;color: #FF5240;">将删除该文件夹及其下的所有文件</span></div>`
    : `<div><p style="font-size: 16px;margin-bottom: 15px;">是否删除所选文件？</p><span style="font-size: 14px;color: #FF5240;">文件将从该路径删除</span></div>`
  ElMessageBox.confirm(des, '删除确认', {
    dangerouslyUseHTMLString: true,
    confirmButtonText: '确认',
    cancelButtonText: '取消'
  }).then(async () => {
    // 删除文件夹传prefix 删除文件传fileNames bucketName都传
    let params
    if (val?.isFolder) {
      //删除文件夹
      params = {
        bucketName: fileQueryData.value.bucketName,
        prefix: val.allName
      }
    } else {
      //删除文件
      params = {
        bucketName: fileQueryData.value.bucketName,
        fileNames: val ? [val.allName] : fileSelectionList.value.map(item => item.allName)
      }
    }
    let res = await sysFileDeleteList(params)
    if (res.code == 20000) {
      ElMessage({
        showClose: true,
        message: `删除成功`,
        type: 'success'
      })
      handleGetBucketFile()
    }
  })
}

// 点击路径面包屑
const handlePrefixClick = val => {
  if (val == prefix.value[prefix.value.length - 1]) {
    //点击本级
    handleGetBucketFile()
  } else if (!val) {
    //点击桶
    prefix.value = []
    fileQueryData.value.prefix = null
    handleGetBucketFile()
  } else {
    //点击路径
    let curIndex = prefix.value.findIndex(item => item == val)
    prefix.value = prefix.value.slice(0, curIndex + 1)
    let curPath = prefix.value.join('/') + '/'
    fileQueryData.value.prefix = curPath
    handleGetBucketFile()
  }
}

// 上一级
const goBack = () => {
  let bucketPath = prefix.value[prefix.value.length - 1]
  let path = prefix.value[prefix.value.length - 2]
  if (path) {
    //有上一级
    handlePrefixClick(path)
  } else if (bucketPath) {
    //上一级是桶
    handlePrefixClick()
  } else {
    emits('update:showBucketList', true)
  }
}

// 下载
const handleDownload = async val => {
  let url = val.url
  let name = `${val.showName}`
  download(url, name)
}

// 文件图标
const getAvatarUrl = type => {
  if (type) {
    return require(`@/assets/sourceManage/${type}.svg`)
  } else {
    return require(`@/assets/sourceManage/folder.svg`)
  }
}
const fileTypes = {
  1: ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'], //图片
  2: ['doc', 'docx'], //文档
  3: ['xls', 'xlsx', 'ods'], //表格
  4: ['ppt', 'pptx', 'odp'], //PPT
  5: ['pdf'], //PDF
  6: ['mp4', 'avi', 'mov', 'mkv'], //视频
  7: ['zip', 'rar'], //压缩包
  8: ['mp3', 'wav', 'ogg', 'flac'], //音频
  9: ['js', 'html', 'css', 'php', 'py'] //其他
}
const getFileType = fileName => {
  // 获取文件的后缀名
  const fileExt = fileName.slice(fileName.lastIndexOf('.'))
  // 将后缀名转换为小写，以便于比较
  const lowerCaseExt = fileExt.toLowerCase()
  // 遍历文件类型，查找匹配的类型
  for (const type in fileTypes) {
    if (fileTypes[type].includes(lowerCaseExt.slice(1))) {
      return type
    }
  }
  // 如果没有匹配的类型，则返回其他
  return '9'
}

const emits = defineEmits(['update:showBucketList'])
// 组件销毁
onUnmounted(() => {
  window.sessionStorage.removeItem('fileQueryData.value')
})

defineExpose({
  fileQueryData,
  handleGetBucketFile
})
</script>
<style scoped lang="scss">
.content-box {
  .top-box {
    width: 100%;
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 20px;
    .bucket-path,
    .file-path {
      cursor: pointer;
      &:hover {
        text-decoration: underline;
      }
    }
    .bucket-path {
      font-weight: bold;
    }
    ::v-deep(.el-page-header) {
      width: 100%;
      margin-right: 20px;
      border: 1px $borderColor solid;
      padding: 8px 10px;
      border-radius: 2px;
      .el-page-header__breadcrumb {
        margin: 0;
      }
      .el-page-header__title {
        display: none;
      }
      .el-page-header__icon {
        margin-right: 0;
      }
      .el-page-header__left .el-divider--vertical {
        margin-left: 10px;
        margin-right: 20px;
      }
    }
  }
  .file-table {
    width: 100%;
    margin-top: 10px;
    .file-item {
      display: flex;
      align-items: center;
      img {
        width: 18px;
        height: 18px;
        margin-right: 5px;
      }
      .file-name {
        cursor: pointer;
        &:hover {
          font-weight: bold;
        }
      }
    }
  }
}
</style>